package com.xiaoq.distribution.consumer;

import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.coms.util.JsonUtil;
import com.xiaoq.distribution.entity.DistriTicketEntity;
import com.xiaoq.distribution.entity.TicketOrderItemEntity;
import com.xiaoq.distribution.service.IAgreementService;
import com.xiaoq.distribution.service.IDistriTicketService;
import com.xiaoq.distribution.service.IDistributorService;
import com.xiaoq.distribution.service.ITicketOrderItemService;
import com.xiaoq.distribution.vo.OrderTicketRequestVo;
import com.xiaoq.shop.service.ISimpleLockService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Created by chenjh on 2018/6/22.
 */
@Component
public class DistributionReceiver extends AbstractReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(DistributionReceiver.class);

    @Autowired
    private IDistributorService distributorSer;
    @Autowired
    private IAgreementService agreementSer;
    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private IDistriTicketService distriTicketSer;
    @Autowired
    private ITicketOrderItemService ticketOrderItemService;

    @Autowired
    private ISimpleLockService simpleLockService;


    @Override
    protected void execute(String message) {

        LOGGER.info("Received Message: " + message);
        OrderTicketRequestVo orderTicketRequestVo = JsonUtil.asObject(message, OrderTicketRequestVo.class);
        String ticketOrderItemId = orderTicketRequestVo.getTicketOrderItemId();
        String distriTicketId = orderTicketRequestVo.getDistriTicketId();

        boolean lockOk = lock(distriTicketId);
        if (!lockOk) {
            LOGGER.error("数据库锁******distriTicketId：" + distriTicketId + "***失败");
            throw new RuntimeException("数据库锁******distriTicketId：" + distriTicketId + "***失败," + message);
        }

        DistriTicketEntity distriTicketEntity = distriTicketSer.findById(distriTicketId);
        if(distriTicketEntity == null){
            simpleLockService.releaseLock(distriTicketId);
            return;   //暂不处理
        }

        TicketOrderItemEntity orderItemEntity = ticketOrderItemService.getById(orderTicketRequestVo.getTicketOrderItemId());
        if(orderItemEntity == null){
            simpleLockService.releaseLock(distriTicketId);
            return;
        }
        if(orderItemEntity != null && orderItemEntity.getSettleMoney() != null){
            simpleLockService.releaseLock(distriTicketId);
            return;  //此消息已处理，直接返回
        }

        long saleCountIndex = distriTicketEntity.getCommitAuthNum();
        long nextSaleCountIndex = saleCountIndex + 1;

        LOGGER.error("nextSaleCountIndex************       " + nextSaleCountIndex);

        long settleMoney = distriTicketEntity.getSettlePrice(nextSaleCountIndex);
        boolean updateSuccessFlag = distriTicketSer.updateTicketCommitCount(distriTicketId, 1);
        if(updateSuccessFlag){
            TicketOrderItemEntity ticketOrderItemEntity = new TicketOrderItemEntity();
            ticketOrderItemEntity.setSettleMoney(settleMoney/100.0);
            ticketOrderItemEntity.setId(ticketOrderItemId);
            ticketOrderItemEntity.setSaleCountIndex(nextSaleCountIndex);
            ticketOrderItemService.updateById(ticketOrderItemEntity);
        }else {
            throw new RuntimeException("数据库更新失败distriTicketId：" + distriTicketId);
        }

        //unlock
        simpleLockService.releaseLock(distriTicketId);
    }


    /**
     * 数据库锁
     * @param distriTicketId
     * @return
     */
    private boolean lock(String distriTicketId){
        //lock
        int lockCount = 0;
        boolean lockOk = false;
        try {
            do {
                if (lockCount != 0) {
                    TimeUnit.SECONDS.sleep(1);
                }
                lockOk = simpleLockService.lock(distriTicketId);
                lockCount++;
            } while (!lockOk && lockCount < 4);
        }catch (Exception e){
            simpleLockService.releaseLock(distriTicketId);
        }

        return lockOk;
    }



}
